/**
 * Copyright 2006 gworks.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 */
package org.javaongems.client.stdctrls;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HasHTML;
import com.google.gwt.user.client.ui.UIObject;

/**
 * A widget that can be placed in a {@link com.google.gwt.user.client.ui.MenuBar}.
 * Menu items can either fire a {@link com.google.gwt.user.client.Command} when
 * they are clicked, or open a cascading sub-menu.
 */
public class MenuItem extends UIObject implements HasHTML {
	final static public String SEPERATOR_DELIM = "<hr/>";
  private Command command;
  private MenuBar parentMenu, subMenu;
  private boolean enabled = true;
  private Image image;
  private HtmlSpan imgCnt = new HtmlSpan();
  private Element imgCntElm = imgCnt.getElement();
  private HtmlSpan captionCnt = new HtmlSpan();
  private Element captionCntElm = captionCnt.getElement();
  private boolean seperator;

  /**
   * Constructs a new menu item that fires a command when it is selected.
   * 
   * @param text the item's text
   * @param cmd the command to be fired when it is selected
   */
  public MenuItem(String text, Command cmd) {
    this(text, false);
    setCommand(cmd);
  }

  /**
   * Constructs a new menu item that fires a command when it is selected.
   * 
   * @param text the item's text
   * @param asHTML <code>true</code> to treat the specified text as html
   * @param cmd the command to be fired when it is selected
   */
  public MenuItem(String text, boolean asHTML, Command cmd) {
    this(text, asHTML);
    setCommand(cmd);
  }

  public MenuItem(String text, boolean asHTML, Command cmd, boolean enable) {
	    this(text, asHTML, cmd);
	    setEnabled(enable);
  }
  
  public MenuItem(String text, boolean asHTML, Command cmd, boolean enable, String imgUrl) {
	    this(text, asHTML, cmd, enable);
	    Image img = new Image(imgUrl);
	    setImage(img);
  }
  
  /**
   * Constructs a new menu item that cascades to a sub-menu when it is selected.
   * 
   * @param text the item's text
   * @param subMenu the sub-menu to be displayed when it is selected
   */
  public MenuItem(String text, MenuBar subMenu) {
    this(text, false);
    setSubMenu(subMenu);
  }

  /**
   * Constructs a new menu item that cascades to a sub-menu when it is selected.
   * 
   * @param text the item's text
   * @param asHTML <code>true</code> to treat the specified text as html
   * @param subMenu the sub-menu to be displayed when it is selected
   */
  public MenuItem(String text, boolean asHTML, MenuBar subMenu) {
    this(text, asHTML);
    setSubMenu(subMenu);
  }

  private MenuItem(String text, boolean asHTML) {
		Element item = DOM.createTD();
		setElement(item);
		sinkEvents(Event.ONCLICK | Event.ONMOUSEOVER | Event.ONMOUSEOUT);
		imgCnt.setWidth("24px");
		DOM.appendChild(item, imgCntElm);
		DOM.setStyleAttribute(imgCntElm, "left", "0");
		DOM.appendChild(item, captionCntElm);
		setSelectionStyle(false);

		if (asHTML)
			setHTML(text);
		else
			setText(text);

		setStyleName("gems-MenuItem");
		seperator = (SEPERATOR_DELIM.equals(text));
		if (seperator)
			setImageContainerVisibility(false);
	}
  
  public boolean isSeparator() {
	  return seperator;
  }

  /**
   * Gets the command associated with this item.
   * 
   * @return this item's command, or <code>null</code> if none exists
   */
  public Command getCommand() {
    return command;
  }

  public String getHTML() {
    return DOM.getInnerHTML(captionCntElm);
  }

  /**
   * Gets the menu that contains this item.
   * 
   * @return the parent menu, or <code>null</code> if none exists.
   */
  public MenuBar getParentMenu() {
    return parentMenu;
  }

  /**
   * Gets the sub-menu associated with this item.
   * 
   * @return this item's sub-menu, or <code>null</code> if none exists
   */
  public MenuBar getSubMenu() {
    return subMenu;
  }

  public String getText() {
    return DOM.getInnerText(captionCntElm);
  }

  /**
   * Sets the command associated with this item.
   * 
   * @param cmd the command to be associated with this item
   */
  public void setCommand(Command cmd) {
    command = cmd;
  }

  public void setHTML(String html) {
    DOM.setInnerHTML(captionCntElm, html);
  }

  /**
   * Sets the sub-menu associated with this item.
   * 
   * @param subMenu this item's new sub-menu
   */
  public void setSubMenu(MenuBar subMenu) {
    this.subMenu = subMenu;
  }

  public void setText(String text) {
    DOM.setInnerText(captionCntElm, text);
  }
  
  public boolean isEnabled() {
	  return enabled;
  }
  
  public void setEnabled(boolean enable) {
	  enabled = enable;
	  setDisabledStyle(!enable);
  }
  
  public Image getImage() {
	  return image;
  }
  
  public void setImage(Image img) {
	  if (image != img) {
		  if (image != null) 
			  DOM.removeChild(imgCntElm, image.getElement());
		  if (img != null)
			  DOM.appendChild(imgCntElm, img.getElement());
	  }
	  image = img;
  }
  
  protected void setImageContainerVisibility(boolean show) {
	  if (isSeparator())
		  show = false;
	  UIObject.setVisible(imgCntElm, show);
  }
    
  protected void setParentMenu(MenuBar parentMenu) {
    this.parentMenu = parentMenu;
  }

  protected void setSelectionStyle(boolean selected) {
	String style = "gems-MenuItem-selected"; 
    if (selected) 
      addStyleName(style);
    else 
      removeStyleName(style);
  }
  
  protected void setDisabledStyle(boolean disabled) {
		String style = "gems-MenuItem-disabled"; 
	    if (disabled) 
	      addStyleName(style);
	    else 
	      removeStyleName(style);
  }
  
}